home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / gfx / 3d / Skulpt_src.lha / sKulpt-src / triangulate.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-26  |  5.5 KB  |  211 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16. #include <d3dx.h>
  17.  
  18. // Includes utilitaires D3D
  19. #include "d3dmath.h"
  20. #include "d3dutil.h"
  21. #include "D3DEnum.h"
  22.  
  23. // Ids Resources
  24. #include "resource.h"
  25.  
  26. // Constantes
  27. #include "const.h"
  28.  
  29. // Types
  30. #include "types.h"
  31.  
  32. // Variables globales projet
  33. #include "vars.h"
  34.  
  35. // Prototypes fonctions autres modules
  36. #include "proto.h"
  37.  
  38. // Macros
  39. #include "macros.h"
  40.  
  41. // Structure d'interface avec le triangulateur Delaunay
  42. #include "triangulator.h"
  43.  
  44. void fill(void)
  45. {
  46.     int iCnt, iVertices, iEdges, iVertex, iEdge, iTriangles, iTriangle, *pTable = NULL;
  47.     triangulateio in, out;
  48.  
  49.      vTrace("Triangulation par méthode Voronoi / Delaunay / Shewchuk / Rupert");
  50.  
  51.     // Calculer le nombre de points (touet la sélection : périphérie + trous)
  52.     iVertices = 0;
  53.     for (iVertex = 0 ; iVertex <= iVertLastUsed ; iVertex++)
  54.         if (bIsVertexSelected(iVertex))
  55.             iVertices++;
  56.  
  57.     vTrace(" * Traitement de %d points", iVertices);
  58.  
  59.     // Si on n'a pas au moins 4 sommets on ne peut pas trianguler
  60.     if (iVertices < 4) return;
  61.  
  62.     // Calculer le nombre de segments
  63.     iEdges = 0;
  64.     for (iEdge = 0 ; iEdge <= iEdgeLastUsed ; iEdge++)
  65.         if (bIsEdgeSelected(iEdge))
  66.             iEdges++;
  67.  
  68.     vTrace(" * Traitement de %d arêtes", iEdges);
  69.  
  70.     // Vérifier la cohérence du nombre de segments par rapport au nombre de points...
  71.     if (iVertices != iEdges)
  72.     {
  73.         vTrace("*** E0030 : Incohérence nombre de sommets / nombre d'arêtes : la structure n'est pas fermée");
  74.         return;
  75.     }
  76.  
  77.     // Préparer la structure d'interface triangulateur
  78.     ZeroMemory(&in, sizeof(in));
  79.     ZeroMemory(&out, sizeof(out));
  80.  
  81.     in.numberofpoints = iVertices;
  82.     if (!(in.pointlist = (double *) malloc(in.numberofpoints * 2 * sizeof(double)))) goto _cleanexit;
  83.  
  84.     in.numberofsegments = iEdges;
  85.     if (!(in.segmentlist = (int *) malloc(in.numberofsegments * 2 * sizeof(int)))) goto _cleanexit;
  86.  
  87.     // Cacher les deux fenêtres 2D non actives
  88.     switch(lWActive)
  89.     {
  90.         case XDC_WID_TOP : // X et Z
  91.             ShowWindow(hWndFace, SW_HIDE);
  92.             ShowWindow(hWndRight, SW_HIDE);
  93.             break;
  94.  
  95.         case XDC_WID_FACE : // X et Y
  96.             ShowWindow(hWndTop, SW_HIDE);
  97.             ShowWindow(hWndRight, SW_HIDE);
  98.             break;
  99.                 
  100.         case XDC_WID_SIDE : // Z et Y
  101.             ShowWindow(hWndTop, SW_HIDE);
  102.             ShowWindow(hWndFace, SW_HIDE);
  103.             break;
  104.     }
  105.  
  106.     // Acquérir la position des trous (trick WM_USER+1 entre 2dWndProc et HoleDlg)
  107.     iHoles = 0;
  108.     //DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOLES), NULL, bHoleDlgProc, 0);
  109.  
  110.     // Positionner les trous
  111.     in.numberofholes = iHoles;
  112.     in.holelist = dHoles;
  113.  
  114.     // Ecrire les coordonnées des points en mémorisant le mapping indices internes / externes
  115.     iCnt = 0;
  116.     if (!(pTable = (int *) malloc(iVertices * sizeof(int)))) goto _cleanexit;
  117.     for (iVertex = 0 ; iVertex <= iVertLastUsed ; iVertex++)
  118.         if (bIsVertexSelected(iVertex))
  119.         {
  120.             switch(lWActive)
  121.             {
  122.                 case XDC_WID_TOP : // X et Z
  123.                     in.pointlist[2 * iCnt + 0]    = Vertices[iVertex].vPoint.x;
  124.                     in.pointlist[2 * iCnt + 1]    = Vertices[iVertex].vPoint.z;
  125.                     break;
  126.  
  127.                 case XDC_WID_FACE : // X et Y
  128.                     in.pointlist[2 * iCnt + 0]    = Vertices[iVertex].vPoint.x;
  129.                     in.pointlist[2 * iCnt + 1]    = Vertices[iVertex].vPoint.y;
  130.                     break;
  131.                         
  132.                 case XDC_WID_SIDE : // Z et Y
  133.                     in.pointlist[2 * iCnt + 0]    = Vertices[iVertex].vPoint.z;
  134.                     in.pointlist[2 * iCnt + 1]    = Vertices[iVertex].vPoint.y;
  135.                     break;
  136.             }
  137.             pTable[iCnt++] = iVertex;
  138.         }
  139.  
  140.     // Ecrire les indices des segments
  141.     iCnt = 0;
  142.     for (iEdge = 0 ; iEdge <= iEdgeLastUsed ; iEdge++)
  143.         if (bIsEdgeSelected(iEdge))
  144.         {
  145.             // Déterminer les indices externes des deux sommets du segment
  146.             int iS0 = -1, iS1 = -1, jCnt = 0;
  147.  
  148.             do
  149.             {
  150.                 if (pTable[jCnt] == Edges[iEdge].iSommets[0]) iS0 = jCnt;
  151.                 if (pTable[jCnt] == Edges[iEdge].iSommets[1]) iS1 = jCnt;
  152.                 jCnt++;
  153.             } while (iS0 == -1 || iS1 == -1);
  154.  
  155.             in.segmentlist[2 * iCnt + 0]    = iS0;
  156.             in.segmentlist[2 * iCnt + 1]    = iS1;
  157.  
  158.             iCnt++;
  159.         }
  160.     
  161.     // Trianguler les points
  162.     triangulate("pzPN", &in, &out, NULL);
  163.  
  164.     // 1 - nombre de triangles
  165.     iTriangles = out.numberoftriangles;
  166.     vTrace(" * %d triangle(s) produit(s)", iTriangles);
  167.  
  168.     // 2 - définition des triangles
  169.     for (iTriangle = 0 ; iTriangle < iTriangles ; iTriangle++)
  170.     {
  171.         int is1, is2, is3;
  172.  
  173.         is1 = pTable[out.trianglelist[iTriangle * 3 + 0]];
  174.         is2 = pTable[out.trianglelist[iTriangle * 3 + 1]];
  175.         is3 = pTable[out.trianglelist[iTriangle * 3 + 2]];
  176.  
  177.         iMakeTriangle(is1, is2, is3, 3);
  178.     }
  179.  
  180.     // Si on a triangulé et qu'il faut supprimer les arêtes, on les supprime
  181.     if (iTriangles && bFillAndRemoveEdges)
  182.         for (iEdge = 0 ; iEdge <= iEdgeLastUsed ; iEdge++)
  183.             if (bIsEdgeSelected(iEdge))
  184.                 bDeleteEdge(iEdge);
  185.  
  186.     // Remontrer les deux fenêtres 2D non actives
  187.     switch(lWActive)
  188.     {
  189.         case XDC_WID_TOP : // X et Z
  190.             ShowWindow(hWndFace, SW_SHOWNA);
  191.             ShowWindow(hWndRight, SW_SHOWNA);
  192.             break;
  193.  
  194.         case XDC_WID_FACE : // X et Y
  195.             ShowWindow(hWndTop, SW_SHOWNA);
  196.             ShowWindow(hWndRight, SW_SHOWNA);
  197.             break;
  198.                 
  199.         case XDC_WID_SIDE : // Z et Y
  200.             ShowWindow(hWndTop, SW_SHOWNA);
  201.             ShowWindow(hWndFace, SW_SHOWNA);
  202.             break;
  203.     }
  204.  
  205. _cleanexit:
  206.     if (pTable) free(pTable);
  207.     if (in.pointlist) free(in.pointlist);
  208.     if (in.segmentlist) free(in.segmentlist);
  209.     if (out.trianglelist) free(out.trianglelist);
  210. }
  211.